// Dispatching a custom event on form submission
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    #loadingSpinner {
      display: none;
      width: 50px;
      height: 50px;
      border: 4px solid #f3f3f3;
      border-top: 4px solid #3498db;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -25px;
      margin-left: -25px;
    }

    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
  </style>
  <title>Form Submission with Custom Events</title>
</head>
<body>

<!-- Спиннер загрузки -->
<div id="loadingSpinner"></div>

<!-- Образец формы -->
<form id="myForm">
  <label for="username">Username:</label>
  <input type="text" id="username" name="username" required>
  <br>
  <label for="password">Password:</label>
  <input type="password" id="password" name="password" required>
  <br>
  <button type="submit">Submit</button>
</form>

<script>
document.addEventListener('DOMContentLoaded', function() {
  // Пользовательское событие для отображения загрузочного спиннера с дополнительными деталями
  const showLoadingSpinnerEvent = new CustomEvent('showLoadingSpinner', {
    detail: {
      message: 'Loading...',
      timestamp: new Date().toLocaleString()
    },
    bubbles: true, // Устанавливаем bubbles в true
  });

  // Пользовательское событие для индикации завершения асинхронной операции с деталями
  const asyncOperationCompleteEvent = new CustomEvent('asyncOperationComplete', {
    detail: {
      message: 'Async operation complete',
      timestamp: new Date().toLocaleString()
    },
    bubbles: true, // Устанавливаем bubbles в true, чтобы событие могло распространяться вверх по DOM
  });

  // Функция обработки отправки формы
  function handleFormSubmit(event) {
    event.preventDefault(); // Предотвращение отправки формы по умолчанию

    // Отправка пользовательского события для отображения спиннера загрузки
    document.dispatchEvent(showLoadingSpinnerEvent);

    // Симуляция асинхронной операции (например, вызов API)
    setTimeout(() => {
      // Отправка пользовательского события при завершении асинхронной операции
      document.dispatchEvent(asyncOperationCompleteEvent);
    }, 2000); // Симуляция двух секундной асинхронной операции
  }

  // Добавление слушателя событий в форму для отправки
  const myForm = document.getElementById('myForm');
  myForm.addEventListener('submit', handleFormSubmit);

  // Слушатель событий для отображения загрузочного спиннера
  document.addEventListener('showLoadingSpinner', function(event) {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'block';
    console.log('Show Loading Spinner:', event.detail);
  });

  // Слушатель события для скрытия загрузочного спиннера после завершения асинхронной операции
  document.addEventListener('asyncOperationComplete', function(event) {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'none';
    console.log('Async Operation Complete:', event.detail);
  });
});
</script>

</body>
</html>
